//
// Created by Administrator on 2025/8/25.
//

#include "lvgl_demo.h"

#include <sys/times.h>

#include "delay.h"
#include "FreeRTOS.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "task.h"
#include "timers.h"
#include "demos/widgets/lv_demo_widgets.h"
#include "dma.h"
#include "sensor_manager.h"
#include "sqlist.h"
#include "printf_rtos.h"
#include "system_api.h"

/**
 * @brief 仪表板页面对象指针
 */
lv_obj_t *dashboard_page;

/**
 * @brief 状态页面对象指针
 */
lv_obj_t *status_page;

/**
 * @brief 传感器注册表外部声明
 */
extern SeqList_t g_sensor_registry;

/**
 * @brief 传感器数据互斥锁外部声明
 */
extern SemaphoreHandle_t sensor_data_mutex;

/**
 * @brief 开关控件样式
 */
static lv_style_t style_switch_knob;

/**
 * @brief 时间标签对象指针
 */
static lv_obj_t *time_label;

/**
 * @brief 时间更新定时器句柄
 */
static TimerHandle_t time_update_timer;

/**
 * @brief 蓝牙图标对象指针
 */
static lv_obj_t *ble_icon;

/**
 * @brief WiFi图标对象指针
 */
static lv_obj_t *wifi_icon;

/**
 * @brief 以太网图标对象指针
 */
static lv_obj_t *eth_icon;

/**
 * @brief 执行器开关任务回调函数
 * 
 * 当用户操作传感器开关控件时调用此函数，根据开关状态控制执行器
 * 
 * @param e 事件对象指针
 */
void actuators_switch_task(struct _lv_event_t *e)
{
    lv_obj_t *sensor_switch=lv_event_get_target(e);
    sensor_config_t* tmp=lv_event_get_user_data(e);
    if (lv_obj_has_state(sensor_switch,LV_STATE_CHECKED)==true)
        tmp->write_func(tmp->slave_addr,tmp->start_addr,(sensor_value_t)1);
    else
        tmp->write_func(tmp->slave_addr,tmp->start_addr,(sensor_value_t)0);
}

/**
 * @brief 状态系统更新回调函数
 * 
 * 定时更新界面中的时间显示和网络状态图标
 * 
 * @param timer 定时器对象指针
 */
void status_sys_update_callback(lv_timer_t *timer)
{
    if (sys_get_ntp_status())
    {
        char time_buf[32]={0};
        struct tm timeinfo;
        sys_get_time(&timeinfo);
        strftime(time_buf,sizeof(time_buf),"%Y-%m-%d %H:%M:%S", &timeinfo);
        lv_label_set_text(time_label,time_buf);
        if (sys_get_ble_status())
            lv_label_set_text(ble_icon,LV_SYMBOL_BLUETOOTH);
        if (sys_get_wifi_status())
            lv_label_set_text(ble_icon,LV_SYMBOL_WIFI);
        if (sys_get_eth_status())
            lv_label_set_text(ble_icon,LV_SYMBOL_DRIVE);
    }
}

/**
 * @brief 创建传感器数据卡片
 * 
 * 根据传感器配置信息创建对应的UI卡片，包括传感器名称和数值显示或控制开关
 * 
 * @param config 传感器配置信息指针
 */
void create_sensor_data_card(sensor_config_t *config)
{
    static char value[32];
    if (config->ui_obj.card==NULL)
    {
        lv_obj_t *card = lv_obj_create(dashboard_page);
        lv_obj_remove_style_all(card);
        lv_obj_set_style_bg_color(card, lv_color_hex(0x2D2D2D), 0);
        lv_obj_set_style_radius(card, 8, 0);
        lv_obj_set_style_pad_all(card, 3, 0);
        lv_obj_set_style_border_color(card, lv_color_hex(0x3B3B3B), 0);
        lv_obj_set_style_border_width(card, 1, 0);
        lv_obj_set_size(card,LV_PCT(100/2-1),LV_PCT(100/4));
        lv_obj_set_layout(card, LV_LAYOUT_FLEX);
        lv_obj_set_flex_flow(card, LV_FLEX_FLOW_ROW);
        lv_obj_set_flex_align(card, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
        lv_obj_t *sensor_name = lv_label_create(card);
        lv_label_set_text(sensor_name, config->name);
        lv_obj_set_style_text_color(sensor_name, lv_color_hex(0xFFFFFF), 0);
        lv_obj_set_style_text_font(sensor_name, &lv_font_montserrat_22, 0);
        lv_obj_set_flex_grow(sensor_name, 1);
        lv_obj_t *sensor_indicator=NULL;
        if (config->direction == SENSOR_DIR_OUTPUT)
        {
            sensor_indicator = lv_label_create(card);
            switch (config->type)
            {
                case SENSOR_DATA_TYPE_FLOAT:
                {
                    int integer_part = (int)config->data.val_float;
                    int fractional_part = (int)((config->data.val_float - integer_part) * 100);
                    snprintf(value, 32, "%d.%02d", integer_part, fractional_part < 0 ? -fractional_part : fractional_part);
                    break;
                }
                case SENSOR_DATA_TYPE_INT:
                    snprintf(value, 32, "%d", config->data.val_int);
                    break;
                case SENSOR_DATA_TYPE_STRING:
                    strncpy(value, config->data.val_string, 31);
                    value[31] = '\0'; // 确保字符串以空字符结尾
                    break;
                default:
                    break;
            }
            lv_label_set_text_fmt(sensor_indicator, "%s%s", value, config->unit);
            lv_obj_set_style_text_color(sensor_indicator, lv_color_hex(0xFFFFFF), 0);
            lv_obj_set_style_text_font(sensor_indicator, &lv_font_montserrat_22, 0);
        } else if (config->direction == SENSOR_DIR_INPUT)
        {
            sensor_indicator = lv_switch_create(card);
            lv_obj_add_style(sensor_indicator, &style_switch_knob, LV_PART_KNOB);
            lv_obj_add_event_cb(sensor_indicator, actuators_switch_task, LV_EVENT_VALUE_CHANGED,config);
        }
        config->ui_obj.card=card;
        config->ui_obj.indicator=sensor_indicator;
    }
    else
    {
        if (config->direction == SENSOR_DIR_OUTPUT)
        {
            switch (config->type)
            {
                case SENSOR_DATA_TYPE_FLOAT:
                {
                    int integer_part = (int)config->data.val_float;
                    int fractional_part = (int)((config->data.val_float - integer_part) * 100);
                    snprintf(value, 32, "%d.%02d", integer_part, fractional_part < 0 ? -fractional_part : fractional_part);
                    break;
                }
                case SENSOR_DATA_TYPE_INT:
                    snprintf(value, 32, "%d", config->data.val_int);
                    break;
                case SENSOR_DATA_TYPE_STRING:
                    strncpy(value, config->data.val_string, 31);
                    value[31] = '\0'; // 确保字符串以空字符结尾
                    break;
                default:
                    break;
            }
            lv_label_set_text_fmt(config->ui_obj.indicator, "%s%s", value, config->unit);
            lv_obj_set_style_text_color(config->ui_obj.indicator, lv_color_hex(0xFFFFFF), 0);
            lv_obj_set_style_text_font(config->ui_obj.indicator, &lv_font_montserrat_22, 0);
        }
    }
}

/**
 * @brief 仪表板更新任务
 * 
 * 周期性地更新仪表板页面中的传感器数据卡片
 * 
 * @param pvParams 任务参数指针（未使用）
 */
void dashboard_update_task(void *pvParams)
{
    UNUSED(pvParams);
    lv_style_init(&style_switch_knob);
    lv_style_set_bg_color(&style_switch_knob, lv_color_white());
    lv_style_set_bg_opa(&style_switch_knob, LV_OPA_COVER);
    lv_style_set_border_color(&style_switch_knob, lv_color_hex(0x007FFF));
    lv_style_set_border_width(&style_switch_knob, 2);
    for (;;)
    {
        // 1. 获取锁，快速复制所有需要的数据到本地
        if (sensor_data_mutex == NULL)
        {
            vTaskDelay(3000);
            continue; // 如果互斥锁未初始化，则跳过此次循环
        }
        // 2. 释放锁之后，再进行耗时的UI操作
        // 先清空所有旧的卡片
        xSemaphoreTake(sensor_data_mutex, portMAX_DELAY);
        // lv_obj_clean(dashboard_page);
        // 遍历本地副本，创建UI卡片
        for (uint8_t i = 0; i < g_sensor_registry.size; i++)
        {
            create_sensor_data_card(&((sensor_config_t *) (g_sensor_registry.data))[i]);
        }
        xSemaphoreGive(sensor_data_mutex);
        size_t uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
        printf_rtos("dashboard stack high water mark: %u words\n", uxHighWaterMark); // 假设你有log_debug
        vTaskDelay(pdMS_TO_TICKS(10000));
    }
}


/**
 * @brief Tab页事件处理函数
 * 
 * 处理Tab按钮点击事件，切换显示状态页面和仪表板页面
 * 
 * @param e 事件对象指针
 */
static void tab_event_handler(lv_event_t *e)
{
    lv_obj_t *obj = lv_event_get_target(e);
    uint32_t id = lv_btnmatrix_get_selected_btn(obj);

    if (id == 0)
    {
        // STATUS 按钮被选中
        lv_obj_clear_flag(status_page, LV_OBJ_FLAG_HIDDEN);
        lv_obj_add_flag(dashboard_page, LV_OBJ_FLAG_HIDDEN);
    } else if (id == 1)
    {
        // DASHBOARD 按钮被选中
        lv_obj_add_flag(status_page, LV_OBJ_FLAG_HIDDEN);
        lv_obj_clear_flag(dashboard_page, LV_OBJ_FLAG_HIDDEN);
    }
}

/**
 * @brief 初始化网关UI界面
 * 
 * 创建整个网关的用户界面，包括标题栏、Tab栏、主体内容和底部信息栏
 */
void ui_gateway_init(void)
{
    lv_obj_t *scr = lv_scr_act();
    lv_obj_set_style_bg_color(scr, lv_color_hex(0x1F1F1F), LV_STATE_DEFAULT);

    static lv_coord_t col_dsc[] = {LV_GRID_FR(1),LV_GRID_TEMPLATE_LAST};
    static lv_coord_t row_dsc[] = {30, 80,LV_GRID_FR(1), 60,LV_GRID_TEMPLATE_LAST};

    lv_obj_set_layout(scr, LV_LAYOUT_GRID);

    lv_obj_set_grid_dsc_array(scr, col_dsc, row_dsc);

    lv_obj_set_style_pad_all(scr, 0, 0);
    lv_obj_set_style_pad_row(scr, 0, 0);
    lv_obj_set_style_pad_column(scr, 0, 0);

    lv_obj_t *title = NULL;
    lv_obj_t *tab = NULL;
    lv_obj_t *body = NULL;
    lv_obj_t *footer = NULL;

    static lv_style_t page_style;
    lv_style_init(&page_style);
    lv_style_set_radius(&page_style, 0);
    lv_style_set_bg_opa(&page_style, LV_OPA_0);
    lv_style_set_border_width(&page_style, 0);
    for (size_t i = 0; i < 4; i++)
    {
        uint8_t row = i;
        lv_obj_t *obj = lv_obj_create(scr);
        lv_obj_remove_style_all(obj);
        lv_obj_add_style(obj, &page_style, 0);
        if (row == 0) title = obj;
        else if (row == 1) tab = obj;
        else if (row == 2) body = obj;
        else if (row == 3) footer = obj;
        lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_STRETCH, row, 1);
        lv_obj_set_style_bg_color(obj, lv_palette_main(i), 0);
        lv_obj_add_style(obj, &page_style, LV_STATE_DEFAULT);
    }
    //通知栏区
    lv_obj_clear_flag(title, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_style_bg_opa(title, LV_OPA_TRANSP, 0);
    lv_obj_set_size(title, 800, 30);
    lv_obj_set_layout(title, LV_LAYOUT_FLEX);
    lv_obj_set_style_pad_all(title, 0, 0);
    lv_obj_set_style_pad_left(title, 10, 0);
    lv_obj_set_style_pad_right(title, 10, 0);
    lv_obj_set_flex_align(title, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_flex_flow(title, LV_FLEX_FLOW_ROW);
    //时间标签容器
    lv_obj_t *time_label_cont = lv_obj_create(title);
    lv_obj_remove_style_all(time_label_cont);
    lv_obj_set_flex_grow(time_label_cont, 1);
    // lv_obj_set_size(time_label_cont,390,30);
    lv_obj_set_layout(time_label_cont, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(time_label_cont, LV_FLEX_FLOW_ROW);
    lv_obj_clear_flag(time_label_cont, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_flex_align(time_label_cont, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_bg_opa(time_label_cont, LV_OPA_0, 0);
    lv_obj_set_style_pad_left(time_label_cont, 0, 0);
    //时间标签
    time_label = lv_label_create(time_label_cont);
    lv_label_set_text(time_label, "Wait for NTP time synchronization");
    lv_obj_set_style_text_font(time_label, &lv_font_montserrat_20, 0);
    lv_obj_set_style_text_color(time_label, lv_color_hex(0xFFFFFF), 0);
    lv_timer_create(status_sys_update_callback,500,NULL);
    //状态图标容器
    lv_obj_t *status_icon_cont = lv_obj_create(title);
    lv_obj_remove_style_all(status_icon_cont);
    lv_obj_set_flex_grow(status_icon_cont, 1);
    // lv_obj_set_size(status_icon_cont,390,30);
    lv_obj_set_layout(status_icon_cont, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(status_icon_cont, LV_FLEX_FLOW_ROW_REVERSE);
    lv_obj_clear_flag(status_icon_cont, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_flex_align(status_icon_cont, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_bg_opa(status_icon_cont, LV_OPA_0, 0);
    lv_obj_set_style_text_color(status_icon_cont, lv_color_white(), 0);
    //图标标签
    wifi_icon = lv_label_create(status_icon_cont);
    lv_label_set_text(wifi_icon,"");
    lv_obj_set_style_text_font(wifi_icon, &lv_font_montserrat_20, 0);
    ble_icon = lv_label_create(status_icon_cont);
    lv_label_set_text(ble_icon,"");
    lv_obj_set_style_text_font(ble_icon, &lv_font_montserrat_20, 0);
    eth_icon = lv_label_create(status_icon_cont);
    lv_label_set_text(eth_icon,"");
    lv_obj_set_style_text_font(eth_icon, &lv_font_montserrat_20, 0);
    //TAB区
    lv_obj_clear_flag(tab, LV_OBJ_FLAG_SCROLLABLE);

    //MBTN区
    //MBTN默认样式
    static lv_style_t mbtn_style_default;
    lv_style_init(&mbtn_style_default);
    lv_style_set_bg_color(&mbtn_style_default, lv_color_hex(0x313131));
    lv_style_set_radius(&mbtn_style_default, 0);
    lv_style_set_text_color(&mbtn_style_default, lv_color_hex(0xFFFFFF));
    lv_style_set_border_width(&mbtn_style_default, 3);
    lv_style_set_border_opa(&mbtn_style_default, LV_OPA_TRANSP);

    //MBTN按下样式
    static lv_style_t mbtn_style_pressed;
    lv_style_init(&mbtn_style_pressed);
    lv_style_set_bg_color(&mbtn_style_pressed, lv_color_hex(0x1F1F1F));
    lv_style_set_text_color(&mbtn_style_pressed, lv_color_hex(0x026EC1));
    lv_style_set_border_color(&mbtn_style_pressed, lv_color_hex(0x026EC1));
    lv_style_set_border_side(&mbtn_style_pressed, LV_BORDER_SIDE_BOTTOM);
    lv_style_set_border_width(&mbtn_style_pressed, 3);
    lv_style_set_border_opa(&mbtn_style_pressed, LV_OPA_COVER);
    //创建MBTN
    lv_obj_t *mbtn1 = lv_btnmatrix_create(tab);
    static const char *mbtn1_map[] = {
        "STATUS",
        "DASHBORAD",
        NULL // 必须以 NULL 结束
    };
    //设置MBTN样式
    lv_btnmatrix_set_map(mbtn1, mbtn1_map);
    lv_obj_set_style_text_font(mbtn1, &lv_font_montserrat_24, 0);
    lv_obj_set_style_bg_color(mbtn1, lv_color_hex(0x1F1F1F), 0);
    lv_btnmatrix_set_one_checked(mbtn1,true);
    lv_btnmatrix_set_btn_ctrl_all(mbtn1, LV_BTNMATRIX_CTRL_CHECKABLE);
    lv_obj_set_style_radius(mbtn1, 0, LV_PART_MAIN);
    lv_obj_set_style_pad_all(mbtn1, 0, LV_PART_MAIN);
    lv_obj_set_style_pad_gap(mbtn1, 3, LV_PART_MAIN);
    lv_obj_set_style_border_width(mbtn1, 0, LV_PART_MAIN);
    lv_obj_align(mbtn1, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_width(mbtn1, 800);
    lv_obj_set_height(mbtn1, 80);
    lv_obj_add_style(mbtn1, &mbtn_style_default, LV_PART_ITEMS);
    lv_obj_add_style(mbtn1, &mbtn_style_pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
    lv_obj_add_style(mbtn1, &mbtn_style_pressed, LV_PART_ITEMS | LV_STATE_CHECKED);
    lv_btnmatrix_set_btn_ctrl(mbtn1, 0, LV_BTNMATRIX_CTRL_CHECKED);
    lv_obj_add_event_cb(mbtn1, tab_event_handler, LV_EVENT_VALUE_CHANGED, NULL);

    //BODY区
    // lv_obj_set_layout(body, LV_LAYOUT_FLEX);
    // lv_obj_set_flex_flow(body, LV_FLEX_FLOW_ROW);
    // lv_obj_set_flex_align(body,LV_FLEX_ALIGN_SPACE_BETWEEN,LV_FLEX_ALIGN_CENTER,LV_FLEX_ALIGN_CENTER);
    // lv_obj_set_flex_grow(body,1);
    // lv_obj_set_style_pad_all(body,0,LV_PART_MAIN);
    lv_obj_set_style_pad_all(body, 10, LV_PART_MAIN);
    static lv_style_t status_info_style;
    lv_style_init(&status_info_style);
    lv_style_set_radius(&status_info_style, 0);
    lv_style_set_bg_opa(&status_info_style, LV_OPA_20);
    lv_style_set_bg_color(&status_info_style, lv_palette_main(LV_PALETTE_GREY));
    lv_style_set_border_width(&status_info_style, 0);
    lv_style_set_text_color(&status_info_style, lv_color_hex(0xFFFFFF));
    lv_style_set_pad_all(&status_info_style, 0);

    lv_style_set_width(&status_info_style, 385);
    lv_style_set_height(&status_info_style, 290);

    static lv_style_t status_info_title_font_style;
    lv_style_init(&status_info_title_font_style);
    lv_style_set_text_color(&status_info_title_font_style, lv_color_hex(0xFFFFFF));
    lv_style_set_text_font(&status_info_title_font_style, &lv_font_montserrat_24);
    lv_style_set_text_align(&status_info_title_font_style, LV_TEXT_ALIGN_LEFT);

    static lv_style_t status_info_title_cont_style;
    lv_style_init(&status_info_title_cont_style);
    lv_style_set_bg_opa(&status_info_title_cont_style, LV_OPA_70);
    lv_style_set_bg_color(&status_info_title_cont_style, lv_color_hex(0x1F1F1F));
    lv_style_set_pad_all(&status_info_title_cont_style, 0);
    lv_style_set_width(&status_info_title_cont_style, 385);
    lv_style_set_height(&status_info_title_cont_style, 40);
    lv_style_set_radius(&status_info_title_cont_style, 0);
    lv_style_set_border_color(&status_info_title_cont_style, lv_color_hex(0x181818));
    lv_style_set_border_side(&status_info_title_cont_style, LV_BORDER_SIDE_BOTTOM);
    //创建status页
    status_page = lv_obj_create(body);
    lv_obj_remove_style_all(status_page);
    lv_obj_set_style_pad_all(status_page, 0, LV_PART_MAIN);
    lv_obj_set_size(status_page,LV_PCT(100),LV_PCT(100));
    lv_obj_set_layout(status_page, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(status_page, LV_FLEX_FLOW_ROW);
    lv_obj_set_flex_align(status_page, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_flex_grow(status_page, 1);

    lv_obj_t *sys_info = lv_obj_create(status_page);
    lv_obj_add_style(sys_info, &status_info_style, 0);
    lv_obj_t *conn_info = lv_obj_create(status_page);
    lv_obj_add_style(conn_info, &status_info_style, 0);

    //系统信息标签容器
    lv_obj_t *sys_info_label_cont = lv_obj_create(sys_info);
    lv_obj_add_style(sys_info_label_cont, &status_info_title_cont_style, 0);
    //系统信息标签
    lv_obj_t *sys_info_label = lv_label_create(sys_info_label_cont);
    lv_obj_add_style(sys_info_label, &status_info_title_font_style, 0);
    lv_obj_align(sys_info_label, LV_ALIGN_TOP_LEFT, 0, 4);
    lv_label_set_text(sys_info_label, "SYSTEM INFORMATION");

    //链接状态标签容器
    lv_obj_t *conn_info_label_cont = lv_obj_create(conn_info);
    lv_obj_add_style(conn_info_label_cont, &status_info_title_cont_style, 0);
    //链接状态标签
    lv_obj_t *conn_info_label = lv_label_create(conn_info_label_cont);
    lv_obj_add_style(conn_info_label, &status_info_title_font_style, 0);
    lv_obj_align(conn_info_label, LV_ALIGN_TOP_LEFT, 0, 4);
    lv_label_set_text(conn_info_label, "CONNECTION STATUS");

    //系统状态内容布局
    lv_obj_t *sys_info_content_layout = lv_obj_create(sys_info);
    lv_obj_remove_style_all(sys_info_content_layout);
    lv_obj_set_size(sys_info_content_layout, 370, 200);
    lv_obj_clear_flag(sys_info_content_layout, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_layout(sys_info_content_layout, LV_LAYOUT_GRID);
    lv_obj_align(sys_info_content_layout, LV_ALIGN_LEFT_MID, 10, 0);
    static lv_coord_t col_dsc_sys_info[] = {120,LV_GRID_FR(1),LV_GRID_TEMPLATE_LAST};
    static lv_coord_t row_dsc_sys_info[] = {40, 40, 40, 40,LV_GRID_TEMPLATE_LAST};
    lv_obj_set_grid_dsc_array(sys_info_content_layout, col_dsc_sys_info, row_dsc_sys_info);
    const char *sys_info_row_labels[] = {"Model:", "Version:", "Uptime:", "Sensors:",NULL};
    for (size_t i = 0; sys_info_row_labels[i] != NULL; i++)
    {
        lv_obj_t *label = lv_label_create(sys_info_content_layout);
        lv_label_set_text(label, sys_info_row_labels[i]);
        lv_obj_set_grid_cell(label, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, i, 1);
        lv_obj_set_style_text_color(label, lv_color_hex(0xFFFFFF), 0);

        lv_obj_t *value_label = lv_label_create(sys_info_content_layout);
        if (i == 0) lv_label_set_text(value_label, "IOT_GW_19Y");
        else if (i == 1) lv_label_set_text(value_label, "1.0.0");
        else if (i == 2) lv_label_set_text(value_label, "12:34:56");
        else if (i == 3) lv_label_set_text(value_label, "3");
        lv_obj_set_grid_cell(value_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, i, 1);
        lv_obj_set_style_text_color(value_label, lv_color_hex(0xFFFFFF), 0);
    }

    //连接状态内容布局
    lv_obj_t *conn_info_content_layout = lv_obj_create(conn_info);
    lv_obj_remove_style_all(conn_info_content_layout);
    lv_obj_set_size(conn_info_content_layout, 370, 45);
    lv_obj_clear_flag(conn_info_content_layout, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_layout(conn_info_content_layout, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(conn_info_content_layout, LV_FLEX_FLOW_ROW);
    lv_obj_set_flex_align(conn_info_content_layout, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START,
                          LV_FLEX_ALIGN_START);
    lv_obj_align(conn_info_content_layout, LV_ALIGN_CENTER, 0, 0);
    lv_obj_t *conn_status_wifi_icon = lv_label_create(conn_info_content_layout);
    lv_label_set_text(conn_status_wifi_icon,LV_SYMBOL_WIFI);
    lv_obj_t *conn_status_ble_icon = lv_label_create(conn_info_content_layout);
    lv_label_set_text(conn_status_ble_icon,LV_SYMBOL_BLUETOOTH);
    lv_obj_t *conn_status_eth_icon = lv_label_create(conn_info_content_layout);
    lv_label_set_text(conn_status_eth_icon,LV_SYMBOL_DRIVE);
    lv_obj_t *conn_status_home_icon = lv_label_create(conn_info_content_layout);
    lv_label_set_text(conn_status_home_icon,LV_SYMBOL_HOME);
    lv_obj_set_style_text_font(conn_status_wifi_icon, &lv_font_montserrat_40, 0);
    lv_obj_set_style_text_font(conn_status_ble_icon, &lv_font_montserrat_40, 0);
    lv_obj_set_style_text_font(conn_status_eth_icon, &lv_font_montserrat_40, 0);
    lv_obj_set_style_text_font(conn_status_home_icon, &lv_font_montserrat_40, 0);
    lv_obj_set_style_text_color(conn_status_wifi_icon, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_color(conn_status_ble_icon, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_color(conn_status_eth_icon, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_color(conn_status_home_icon, lv_color_hex(0xFFFFFF), 0);
    lv_obj_t *conn_status_label = lv_label_create(conn_info);
    lv_obj_align(conn_status_label, LV_ALIGN_BOTTOM_MID, 0, 0);
    lv_label_set_text(conn_status_label, "All Connected");
    lv_obj_set_style_text_font(conn_status_label, &lv_font_montserrat_30, 0);
    lv_obj_set_style_text_color(conn_status_label, lv_color_hex(0x7CFC00), 0);

    //Dashboard页
    dashboard_page = lv_obj_create(body);
    lv_obj_add_flag(dashboard_page, LV_OBJ_FLAG_HIDDEN);
    lv_obj_remove_style_all(dashboard_page);
    lv_obj_add_flag(dashboard_page, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_size(dashboard_page,LV_PCT(100),LV_PCT(100));
    lv_obj_set_layout(dashboard_page, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(dashboard_page, LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_set_style_pad_column(dashboard_page, 5, 0); // 列间距 (卡片水平间距)
    lv_obj_set_style_pad_row(dashboard_page, 5, 0); // 行间距 (卡片垂直间距)
    lv_obj_set_flex_align(dashboard_page, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START);
    // lv_obj_set_flex_grow(dashboard_page,1);


    //底栏信息布局
    lv_obj_t *info_layout = lv_obj_create(footer);
    lv_obj_clear_flag(info_layout, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_layout(info_layout, LV_LAYOUT_FLEX);
    lv_obj_set_style_bg_opa(info_layout, LV_OPA_0, 0);
    lv_obj_set_style_border_opa(info_layout, LV_OPA_0, 0);

    lv_obj_set_flex_flow(info_layout, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_style_radius(info_layout, 0, 0);
    lv_obj_align(info_layout, LV_ALIGN_LEFT_MID, 0, 0);
    lv_obj_set_size(info_layout, 300, 60);
    lv_obj_set_flex_align(info_layout, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
    lv_obj_set_style_pad_row(info_layout, 0, 0);
    lv_obj_set_style_pad_left(info_layout, 0, 0);
    //底栏区
    lv_obj_set_layout(footer, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(footer, LV_FLEX_FLOW_ROW);
    lv_obj_set_style_bg_color(footer, lv_color_hex(0x181818), 0);
    lv_obj_set_style_bg_opa(footer, LV_OPA_100, 0);
    lv_obj_set_flex_align(footer, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_pad_left(footer, 10, LV_PART_MAIN);
    lv_obj_set_style_pad_right(footer, 10, LV_PART_MAIN);
    lv_obj_t *ip_label = lv_label_create(info_layout);
    lv_obj_clear_flag(footer, LV_OBJ_FLAG_SCROLLABLE);
    lv_label_set_text_fmt(ip_label, "IP:%s", "10.0.0.1");
    lv_obj_t *update_label = lv_label_create(info_layout);
    lv_label_set_text_fmt(update_label, "time:%s", "2025-09-08");
    lv_obj_set_style_text_align(ip_label, LV_TEXT_ALIGN_LEFT, 0);
    lv_obj_set_style_text_color(ip_label, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_color(update_label, lv_color_hex(0xFFFFFF), 0);
    //重启按钮
    lv_obj_t *reboot_btn = lv_btn_create(footer);
    lv_obj_set_size(reboot_btn, 50, 50);
    lv_obj_set_style_radius(reboot_btn, 25, LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(reboot_btn, lv_palette_main(LV_PALETTE_BLUE), 0); // 给按钮一个颜色
    lv_obj_set_style_shadow_width(reboot_btn, 0, 0); // 去掉阴影
    lv_obj_t *reboot_icon = lv_label_create(reboot_btn);
    lv_label_set_text(reboot_icon, LV_SYMBOL_REFRESH);
    lv_obj_set_style_text_color(reboot_icon, lv_color_white(), 0);
    lv_obj_center(reboot_icon);
}

/**
 * @brief 启动LVGL界面任务
 * 
 * 创建并启动LVGL界面任务
 */
void lvgl_start(void)
{
    taskENTER_CRITICAL();
        xTaskCreate(lvgl_interface_task, "lvgl_interface_task", 2048, NULL, tskIDLE_PRIORITY + 5, NULL);
    taskEXIT_CRITICAL();
}

/**
 * @brief LVGL界面任务函数
 * 
 * 初始化LVGL库和相关端口，然后周期性地处理LVGL事件
 * 
 * @param pvParams 任务参数指针（未使用）
 */
void lvgl_interface_task(void *pvParams)
{
    UNUSED(pvParams);
    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();
    ui_gateway_init();
    // lv_demo_widgets();

    for (;;)
    {
        lv_task_handler();
        vTaskDelay(30);
        // size_t uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
        // printf_rtos("lvgl_handler stack high water mark: %u words\n", uxHighWaterMark); // 假设你有log_debug
    }
}
